home *** CD-ROM | disk | FTP | other *** search
/ OpenGL Superbible (2nd Edition) / OpenGL SuperBible e2.iso / tools / OpenGL / OPENGL2.EXE / _SETUP.1 / simpleci.c < prev    next >
Encoding:
C/C++ Source or Header  |  1997-11-21  |  12.2 KB  |  499 lines

  1. /*
  2. ** Simple Color Index Example
  3. */
  4. #include <windows.h>
  5. #include <math.h>
  6. #include <GL/gl.h>
  7.  
  8. #if !defined(M_PI)
  9. #define M_PI 3.14159265F
  10. #endif
  11.  
  12. char *className = "OpenGL";
  13. char *windowName = "Simple Color Index";
  14. int winX = 0, winY = 0;
  15. int winWidth = 300, winHeight = 300;
  16.  
  17. HDC hDC;
  18. HGLRC hGLRC;
  19. HPALETTE hPalette;
  20.  
  21. void (*idleFunc)(void);
  22.  
  23. /* Struct used to manage color ramps */
  24. struct colorIndexState {
  25.     GLfloat amb[3];    /* ambient color / bottom of ramp */
  26.     GLfloat diff[3];    /* diffuse color / middle of ramp */
  27.     GLfloat spec[3];    /* specular color / top of ramp */
  28.     GLfloat ratio;    /* ratio of diffuse to specular in ramp */
  29.     GLint indexes[3];    /* where ramp was placed in palette */
  30. };
  31.  
  32. /*
  33. ** Each entry in this array corresponds to a color ramp in the
  34. ** palette.  The indexes member of each struct is updated to
  35. ** reflect the placement of the color ramp in the palette.
  36. */
  37. #define NUM_COLORS (sizeof(colors) / sizeof(colors[0]))
  38. struct colorIndexState colors[] = {
  39.     {
  40.         { 0.0F, 0.0F, 0.0F },
  41.         { 0.1F, 0.6F, 0.3F },
  42.         { 1.0F, 1.0F, 1.0F },
  43.         0.75F, { 0, 0, 0 },
  44.     },
  45.     {
  46.         { 0.0F, 0.0F, 0.0F },
  47.         { 0.0F, 0.2F, 0.5F },
  48.         { 1.0F, 1.0F, 1.0F },
  49.         0.75F, { 0, 0, 0 },
  50.     },
  51.     {
  52.         { 0.0F, 0.05F, 0.05F },
  53.         { 0.6F, 0.0F, 0.8F },
  54.         { 1.0F, 1.0F, 1.0F },
  55.         0.75F, { 0, 0, 0 },
  56.     },
  57. };
  58.  
  59. void
  60. drawTorus(void)
  61. {
  62.     int numMajor = 32;
  63.     int numMinor = 24;
  64.     float majorRadius = 0.6F;
  65.     float minorRadius = 0.2F;
  66.     double majorStep = 2.0F*M_PI / numMajor;
  67.     double minorStep = 2.0F*M_PI / numMinor;
  68.     int i, j;
  69.  
  70.     for (i=0; i<numMajor; ++i) {
  71.     double a0 = i * majorStep;
  72.     double a1 = a0 + majorStep;
  73.     GLfloat x0 = (GLfloat) cos(a0);
  74.     GLfloat y0 = (GLfloat) sin(a0);
  75.     GLfloat x1 = (GLfloat) cos(a1);
  76.     GLfloat y1 = (GLfloat) sin(a1);
  77.  
  78.     if (i & 1) {
  79.         glMaterialiv(GL_FRONT, GL_COLOR_INDEXES, colors[0].indexes);
  80.     } else {
  81.         glMaterialiv(GL_FRONT, GL_COLOR_INDEXES, colors[1].indexes);
  82.     }
  83.  
  84.     glBegin(GL_TRIANGLE_STRIP);
  85.     for (j=0; j<=numMinor; ++j) {
  86.         double b = j * minorStep;
  87.         GLfloat c = (GLfloat) cos(b);
  88.         GLfloat r = minorRadius * c + majorRadius;
  89.         GLfloat z = minorRadius * (GLfloat) sin(b);
  90.  
  91.         glNormal3f(x0*c, y0*c, z/minorRadius);
  92.         glVertex3f(x0*r, y0*r, z);
  93.  
  94.         glNormal3f(x1*c, y1*c, z/minorRadius);
  95.         glVertex3f(x1*r, y1*r, z);
  96.     }
  97.     glEnd();
  98.     }
  99. }
  100.  
  101. /*****************************************************************/
  102.  
  103. void
  104. setProjection(void)
  105. {
  106.     glMatrixMode(GL_PROJECTION);
  107.     glLoadIdentity();
  108.     /*
  109.     ** Preserve the aspect ratio of objects in the scene.
  110.     */
  111.     if (winWidth > winHeight) {
  112.     GLfloat aspect = (GLfloat) winWidth / (GLfloat) winHeight;
  113.     glFrustum(-0.5F*aspect, 0.5F*aspect, -0.5F, 0.5F, 1.0F, 3.0F);
  114.     } else {
  115.     GLfloat aspect = (GLfloat) winHeight / (GLfloat) winWidth;
  116.     glFrustum(-0.5F, 0.5F, -0.5F*aspect, 0.5F*aspect, 1.0F, 3.0F);
  117.     }
  118.     glMatrixMode(GL_MODELVIEW);
  119. }
  120.  
  121. void
  122. init(void)
  123. {
  124.     GLfloat matShine = 20.00F;
  125.     GLfloat light0Pos[4] = { 0.70F, 0.70F, 1.25F, 0.00F };
  126.  
  127.     glClearIndex((GLfloat) colors[2].indexes[1]);
  128.  
  129.     setProjection();
  130.     glTranslatef(0.0F, 0.0F, -2.0F);
  131.  
  132.     glMaterialf(GL_FRONT_AND_BACK, GL_SHININESS, matShine);
  133.     glLightfv(GL_LIGHT0, GL_POSITION, light0Pos);
  134.     glEnable(GL_LIGHT0);
  135.  
  136.     glEnable(GL_LIGHTING);
  137.     glEnable(GL_DEPTH_TEST);
  138. }
  139.  
  140. void
  141. doRedraw(void)
  142. {
  143.     static GLfloat x, y, z;
  144.  
  145.     glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
  146.  
  147.     glPushMatrix();
  148.     glRotatef(x, 1.0F, 0.0F, 0.0F);
  149.     glRotatef(y, 0.0F, 1.0F, 0.0F);
  150.     glRotatef(z, 0.0F, 0.0F, 1.0F);
  151.  
  152.     drawTorus();
  153.  
  154.     glPopMatrix();
  155.  
  156.     SwapBuffers(hDC);
  157.  
  158.     x += 5.0F;
  159.     if (x > 360.0F) x -= 360.0F;
  160.     y += 7.0F;
  161.     if (y > 360.0F) y -= 360.0F;
  162.     z += 9.0F;
  163.     if (z > 360.0F) z -= 360.0F;
  164. }
  165.  
  166. void
  167. redraw(void)
  168. {
  169.     idleFunc = doRedraw;
  170. }
  171.  
  172. void
  173. resize(void)
  174. {
  175.     setProjection();
  176.     glViewport(0, 0, winWidth, winHeight);
  177. }
  178.  
  179. /*****************************************************************/
  180.  
  181. void
  182. setupPalette(HDC hDC)
  183. {
  184.     PIXELFORMATDESCRIPTOR pfd;
  185.     LOGPALETTE* pPal;
  186.     int pixelFormat = GetPixelFormat(hDC);
  187.     int paletteSize;
  188.  
  189.     DescribePixelFormat(hDC, pixelFormat, sizeof(PIXELFORMATDESCRIPTOR), &pfd);
  190.  
  191.     /*
  192.     ** Determine if a palette is needed and if so what size.
  193.     */
  194.     if (pfd.dwFlags & PFD_NEED_PALETTE ||
  195.         pfd.iPixelType == PFD_TYPE_COLORINDEX) {
  196.     paletteSize = 1 << pfd.cColorBits;
  197.     if (paletteSize > 4096) {
  198.         paletteSize = 4096;
  199.     }
  200.     } else {
  201.     return;
  202.     }
  203.  
  204.     pPal = (LOGPALETTE*)
  205.     malloc(sizeof(LOGPALETTE) + paletteSize * sizeof(PALETTEENTRY));
  206.     pPal->palVersion = 0x300;
  207.     pPal->palNumEntries = paletteSize;
  208.  
  209.     /*
  210.     ** Fill the logical palette with color ramps.
  211.     **
  212.     ** Set up the logical palette so that it can be realized
  213.     ** into the system palette as an identity palette.
  214.     **
  215.     ** 1) The default static entries should be present and at the right
  216.     **    location.  The easiest way to do this is to grab them from
  217.     **    the current system palette.
  218.     **
  219.     ** 2) All non-static entries should be initialized to unique values.
  220.     **    The easiest way to do this is to ensure that all of the non-static
  221.     **    entries have the PC_NOCOLLAPSE flag bit set.
  222.     */
  223.     {
  224.     int numRamps = NUM_COLORS;
  225.     int rampSize = (paletteSize - 20) / numRamps;
  226.     int extra = (paletteSize - 20) - (numRamps * rampSize);
  227.     int i, r;
  228.  
  229.     /*
  230.     ** Initialize static entries by copying them from the
  231.     ** current system palette.
  232.     */
  233.     GetSystemPaletteEntries(hDC, 0, paletteSize, &pPal->palPalEntry[0]);
  234.  
  235.     /*
  236.     ** Fill in non-static entries with desired colors.
  237.     */
  238.     for (r=0; r<numRamps; ++r) {
  239.         int rampBase = r * rampSize + 10;
  240.         PALETTEENTRY *pe = &pPal->palPalEntry[rampBase];
  241.         int diffSize = (int) (rampSize * colors[r].ratio);
  242.         int specSize = rampSize - diffSize;
  243.  
  244.         for (i=0; i<rampSize; ++i) {
  245.         GLfloat *c0, *c1;
  246.         GLint a;
  247.  
  248.         if (i < diffSize) {
  249.             c0 = colors[r].amb;
  250.             c1 = colors[r].diff;
  251.             a = (i * 255) / (diffSize - 1);
  252.         } else {
  253.             c0 = colors[r].diff;
  254.             c1 = colors[r].spec;
  255.             a = ((i - diffSize) * 255) / (specSize - 1);
  256.         }
  257.  
  258.         pe[i].peRed = (BYTE) (a * (c1[0] - c0[0]) + 255 * c0[0]);
  259.         pe[i].peGreen = (BYTE) (a * (c1[1] - c0[1]) + 255 * c0[1]);
  260.         pe[i].peBlue = (BYTE) (a * (c1[2] - c0[2]) + 255 * c0[2]);
  261.         pe[i].peFlags = PC_NOCOLLAPSE;
  262.         }
  263.  
  264.         colors[r].indexes[0] = rampBase;
  265.         colors[r].indexes[1] = rampBase + (diffSize-1);
  266.         colors[r].indexes[2] = rampBase + (rampSize-1);
  267.     }
  268.  
  269.     /*
  270.     ** Initialize any remaining non-static entries.
  271.     */
  272.     for (i=0; i<extra; ++i) {
  273.         int index = numRamps*rampSize+10+i;
  274.         PALETTEENTRY *pe = &pPal->palPalEntry[index];
  275.  
  276.         pe->peRed = (BYTE) 0;
  277.         pe->peGreen = (BYTE) 0;
  278.         pe->peBlue = (BYTE) 0;
  279.         pe->peFlags = PC_NOCOLLAPSE;
  280.     }
  281.     }
  282.  
  283.     hPalette = CreatePalette(pPal);
  284.     free(pPal);
  285.  
  286.     if (hPalette) {
  287.     SelectPalette(hDC, hPalette, FALSE);
  288.     RealizePalette(hDC);
  289.     }
  290. }
  291.  
  292. void
  293. setupPixelFormat(HDC hDC)
  294. {
  295.     PIXELFORMATDESCRIPTOR pfd = {
  296.     sizeof(PIXELFORMATDESCRIPTOR),    /* size of this pfd */
  297.     1,                /* version num */
  298.     PFD_DRAW_TO_WINDOW |        /* support window */
  299.     PFD_SUPPORT_OPENGL |        /* support OpenGL */
  300.     PFD_DOUBLEBUFFER,        /* support double-buffering */
  301.     PFD_TYPE_COLORINDEX,        /* color index mode */
  302.     8,                /* 8-bit color depth */
  303.     0, 0, 0, 0, 0, 0,        /* color bits (ignored) */
  304.     0,                /* no alpha buffer */
  305.     0,                /* alpha bits (ignored) */
  306.     0,                /* no accumulation buffer */
  307.     0, 0, 0, 0,            /* accum bits (ignored) */
  308.     16,                /* depth buffer */
  309.     0,                /* no stencil buffer */
  310.     0,                /* no auxiliary buffers */
  311.     PFD_MAIN_PLANE,            /* main layer */
  312.     0,                /* reserved */
  313.     0, 0, 0,            /* no layer, visible, damage masks */
  314.     };
  315.     int SelectedPixelFormat;
  316.     BOOL retVal;
  317.  
  318.     SelectedPixelFormat = ChoosePixelFormat(hDC, &pfd);
  319.     if (SelectedPixelFormat == 0) {
  320.     MessageBox(WindowFromDC(hDC),
  321.         "ChoosePixelFormat failed\n"
  322.         "This application works best with an 8-bit\n"
  323.         "(256 color) display mode\n",
  324.         "Error",
  325.         MB_ICONERROR | MB_OK);
  326.     exit(1);
  327.     }
  328.  
  329.     retVal = SetPixelFormat(hDC, SelectedPixelFormat, &pfd);
  330.     if (retVal != TRUE) {
  331.     MessageBox(WindowFromDC(hDC), "SetPixelFormat failed", "Error",
  332.         MB_ICONERROR | MB_OK);
  333.     exit(1);
  334.     }
  335. }
  336.  
  337. LRESULT APIENTRY
  338. WndProc(
  339.     HWND hWnd,
  340.     UINT message,
  341.     WPARAM wParam,
  342.     LPARAM lParam)
  343. {
  344.     switch (message) {
  345.     case WM_CREATE:
  346.     /*
  347.     ** Set up for OpenGL rendering.  Bind the rendering context to
  348.     ** the same device context that the palette will be selected into.
  349.     */
  350.     hDC = GetDC(hWnd);
  351.     setupPixelFormat(hDC);
  352.     setupPalette(hDC);
  353.     hGLRC = wglCreateContext(hDC);
  354.     wglMakeCurrent(hDC, hGLRC);
  355.     init();
  356.     idleFunc = doRedraw;
  357.     return 0;
  358.     case WM_DESTROY:
  359.     /*
  360.     ** Finish OpenGL rendering.
  361.     */
  362.     idleFunc = NULL;
  363.     if (hGLRC) {
  364.         wglMakeCurrent(NULL, NULL);
  365.         wglDeleteContext(hGLRC);
  366.     }
  367.     ReleaseDC(hWnd, hDC);
  368.     PostQuitMessage(0);
  369.     return 0;
  370.     case WM_SIZE:
  371.     if (hGLRC) {
  372.         winWidth = (int) LOWORD(lParam);
  373.         winHeight = (int) HIWORD(lParam);
  374.         resize();
  375.         return 0;
  376.     }
  377.     case WM_PALETTECHANGED:
  378.     /*
  379.     ** Update palette mapping if this *is not* the active window.
  380.     */
  381.     if (hGLRC && hPalette && (HWND) wParam != hWnd) {
  382.         UnrealizeObject(hPalette);
  383.         SelectPalette(hDC, hPalette, FALSE);
  384.         RealizePalette(hDC);
  385.         redraw();
  386.         return 0;
  387.     }
  388.     break;
  389.     case WM_QUERYNEWPALETTE:
  390.     /*
  391.     ** Update palette mapping if this *is* the active window.
  392.     */
  393.     if (hGLRC && hPalette) {
  394.         UnrealizeObject(hPalette);
  395.         SelectPalette(hDC, hPalette, FALSE);
  396.         RealizePalette(hDC);
  397.         redraw();
  398.         return TRUE;
  399.     }
  400.     break;
  401.     case WM_PAINT:
  402.     /*
  403.     ** Update the window.  Don't use the device context returned by
  404.     ** BeginPaint as it won't have the right palette selected into it.
  405.     */
  406.     if (hGLRC) {
  407.         PAINTSTRUCT ps;
  408.  
  409.         BeginPaint(hWnd, &ps);
  410.         redraw();
  411.         EndPaint(hWnd, &ps);
  412.         return 0;
  413.     }
  414.     break;
  415.     case WM_CHAR:
  416.     switch ((int)wParam) {
  417.     case VK_ESCAPE:
  418.         DestroyWindow(hWnd);
  419.         return 0;
  420.     default:
  421.         break;
  422.     }
  423.     break;
  424.     default:
  425.     break;
  426.     }
  427.  
  428.     /* Deal with any unprocessed messages */
  429.     return DefWindowProc(hWnd, message, wParam, lParam);
  430. }
  431.  
  432. int APIENTRY
  433. WinMain(
  434.     HINSTANCE hCurrentInst,
  435.     HINSTANCE hPreviousInst,
  436.     LPSTR lpszCmdLine,
  437.     int nCmdShow)
  438. {
  439.     WNDCLASS wndClass;
  440.     HWND hWnd;
  441.     MSG msg;
  442.  
  443.     /* Define and register a window class */
  444.     wndClass.style = CS_OWNDC | CS_HREDRAW | CS_VREDRAW;
  445.     wndClass.lpfnWndProc = WndProc;
  446.     wndClass.cbClsExtra = 0;
  447.     wndClass.cbWndExtra = 0;
  448.     wndClass.hInstance = hCurrentInst;
  449.     wndClass.hIcon = LoadIcon(NULL, IDI_APPLICATION);
  450.     wndClass.hCursor = LoadCursor(NULL, IDC_ARROW);
  451.     wndClass.hbrBackground = GetStockObject(WHITE_BRUSH);
  452.     wndClass.lpszMenuName = NULL;
  453.     wndClass.lpszClassName = className;
  454.     RegisterClass(&wndClass);
  455.  
  456.     /* Figure out a default size for the window */
  457.     winWidth = GetSystemMetrics(SM_CYSCREEN) / 3;
  458.     winHeight = GetSystemMetrics(SM_CYSCREEN) / 3;
  459.  
  460.     /* Create a window of the previously defined class */
  461.     hWnd = CreateWindow(
  462.     className,        /* Window class's name */
  463.     windowName,        /* Title bar text */
  464.     WS_OVERLAPPEDWINDOW |    /* The window's style */
  465.     WS_CLIPCHILDREN |
  466.     WS_CLIPSIBLINGS,
  467.     winX, winY,        /* Position */
  468.     winWidth, winHeight,    /* Size */
  469.     NULL,            /* Parent window's handle */
  470.     NULL,            /* Menu handle */
  471.     hCurrentInst,        /* Instance handle */
  472.     NULL);            /* No additional data */
  473.  
  474.     /* Map the window to the screen */
  475.     ShowWindow(hWnd, nCmdShow);
  476.  
  477.     /* Force the window to repaint itself */
  478.     UpdateWindow(hWnd);
  479.  
  480.     /* Process Messages */
  481.     while (1) {
  482.     /* execute the idle function while there are no messages to process */
  483.     while (idleFunc &&
  484.            PeekMessage(&msg, NULL, 0, 0, PM_NOREMOVE) == FALSE)
  485.     {
  486.         (*idleFunc)();
  487.     }
  488.     if (GetMessage(&msg, NULL, 0, 0) != TRUE) {
  489.         break;
  490.     }
  491.     TranslateMessage(&msg);
  492.     DispatchMessage(&msg);
  493.     }
  494.  
  495.     return msg.wParam;
  496. }
  497.  
  498. 
  499.